package app.framework.security.captcha;

import app.framework.constant.FrontConstants;
import app.framework.constant.FrameworkErrorConstants;
import app.framework.constant.FrameworkMsgConstants;
import app.framework.front.util.WebUtil;
import jasmine.framework.common.util.CheckUtil;
import jasmine.framework.common.util.I18nUtil;
import jasmine.framework.common.util.JsonUtil;
import jasmine.framework.web.entity.WebResult;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author mh.z
 */
public class CaptchaFilter implements Filter {
    private RequestMatcher requestMatcher;

    private static final String CAPTCHA_KEY_PARAM_NAME = "captchaKey";
    private static final String CAPTCHA_CODE_PARAM_NAME = "captchaCode";

    public CaptchaFilter(RequestMatcher requestMatcher) {
        this.requestMatcher = requestMatcher;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        if (requestMatcher.matches(httpRequest)) {
            String captchaKey = obtainCaptchaKey(httpRequest);
            String captchaCode = obtainCaptchaCode(httpRequest);
            boolean checkResult = CaptchaCacheUtil.check(captchaKey, captchaCode);

            // 无论是否匹配成功都从缓存中清除
            CaptchaCacheUtil.remove(captchaKey);

            if (!checkResult) {
                sendErrorResult((HttpServletResponse) response);
                return;
            }
        }

        chain.doFilter(request, response);
    }

    /**
     * 返回验证码对应的 key
     *
     * @param request
     * @return
     */
    protected String obtainCaptchaKey(HttpServletRequest request) {
        return request.getParameter(CAPTCHA_KEY_PARAM_NAME);
    }

    /**
     * 返回验证码对应的代码
     *
     * @param request
     * @return
     */
    protected String obtainCaptchaCode(HttpServletRequest request) {
        return request.getParameter(CAPTCHA_CODE_PARAM_NAME);
    }

    /**
     * 发送错误结果
     *
     * @param response
     */
    protected void sendErrorResult(HttpServletResponse response) {
        CheckUtil.notNull(response, "response null");

        // 设置响应体信息
        WebUtil.setResponseInfo(response, HttpServletResponse.SC_OK,
                FrontConstants.RESPONSE_CONTENT_TYPE_JSON);

        String message = I18nUtil.getMessage(FrameworkMsgConstants.WRONG_CAPTCHA_CODE);
        WebResult result = WebResult.error(FrameworkErrorConstants.WRONG_CAPTCHA_CODE, message);
        String json = JsonUtil.toJson(result);

        // 写入数据到响应体
        WebUtil.writeAndFlush(response, json);
    }

}
